package com.xwltz.database.mybatisplus.config;

import com.xwltz.cache.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.util.DigestUtils;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @description MybatisPlusRedisCache
 * @information on version 1.0 be created by @xwltz at 2022/5/5 10:55
 */
@Slf4j
@SuppressWarnings("unused")
public class MybatisPlusRedisCache implements Cache {

	// 读写锁
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

	private final String id;

	public MybatisPlusRedisCache(final String id) {
		if (id == null) {
			throw new IllegalArgumentException("Cache instances require an ID");
		}
		this.id = id;
	}


	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public void putObject(Object key, Object value) {
		try {
			//将key加密后存入
			RedisCache.HASH.hashPut(this.id, this.MD5Encrypt(key), value);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public Object getObject(Object key) {
		try {
			if (key != null) {
				return RedisCache.HASH.hashGet(this.id, this.MD5Encrypt(key));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Object removeObject(Object key) {
		try {
			if (key != null) {
				RedisCache.HASH.hashDelete(this.MD5Encrypt(key));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void clear() {
		try {
			RedisCache.HASH.redisTemplate.delete(this.id);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public int getSize() {
		Long size = RedisCache.HASH.redisTemplate.execute(RedisServerCommands::dbSize);
		assert size != null;
		return size.intValue();
	}

	@Override
	public ReadWriteLock getReadWriteLock() {
		return this.readWriteLock;
	}

	/**
	 * MD5加密存储key,以节约内存
	 */
	private String MD5Encrypt(Object key) {
		return DigestUtils.md5DigestAsHex(key.toString().getBytes());
	}
}
